/**
  * @(#)WeekDay.java 
  *
  * Week Day enumeration for section days of the week
  *
  * @author Course Scheduler Team
  * 
  * @license GNU General Public License version 3 (GPLv3)
  *
  * This file is part of Course Scheduler, an open source, cross platform
  * course scheduling tool, configurable for most universities.
  *
  * Copyright (C) 2010-2012 Course Scheduler Team
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * 
  */
package com.pollicitus.scheduler.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.pollicitus.scheduler.model.ConcretelyAnnouncable;
import com.pollicitus.scheduler.model.WeekDay;
import com.pollicitus.scheduler.util.Enumeration;

/**
 * Week Day enumeration for section days of the week
 * 
 * @author Course Scheduler Team
 *
 */
public class WeekDay extends Enumeration<WeekDay> implements ConcretelyAnnouncable {

	/**
	 * The most recent revision in which this file was changed in the source control system
	 */
	public static final String _revision = "$LastChangedRevision: 539 $";
	
	/**
	 * The date on which this file was last changed and submitted to source control
	 */
	public static final String _date = "$LastChangedDate: 2011-11-19 23:14:16 -0500 (Sat, 19 Nov 2011) $";
	
	/**
	 * The user which last changed the file and committed the change to source control
	 */
	public static final String _author = "$LastChangedBy: mike@pollicitus.com $";
	
	/**
	 * The URL which can be used to access this specific file within the source control system
	 */
	public static final String _headURL = "$HeadURL: https://courseschedulerx.googlecode.com/svn/trunk/course-scheduler/course-scheduler-core/src/main/java/com/pollicitus/scheduler/model/WeekDay.java $";
	
	/**
	 * The source control file ID, comprised of the file name, latest revision, last changed date, and submitting user.
	 */
	public static final String _id = "$Id: WeekDay.java 539 2011-11-20 04:14:16Z mike@pollicitus.com $";
		
	//protected static class variables
	protected static Map<String, WeekDay> values = new HashMap<String, WeekDay>();
	
	//enumeration values
	public static WeekDay SUNDAY = new WeekDay("SUNDAY", "Sunday", 0, 'U', true);
	public static WeekDay MONDAY = new WeekDay("MONDAY", "Monday", 1, 'M', true);
	public static WeekDay TUESDAY = new WeekDay("TUESDAY", "Tuesday", 2, 'T', true);
	public static WeekDay WEDNESDAY = new WeekDay("WEDNESDAY", "Wednesday", 3, 'W', true);
	public static WeekDay THURSDAY = new WeekDay("THURSDAY", "Thursday", 4, 'R', true);
	public static WeekDay FRIDAY = new WeekDay("FRIDAY", "Friday", 5, 'F', true);
	public static WeekDay SATURDAY = new WeekDay("SATURDAY", "Saturday", 6, 'S', true);
	public static WeekDay TBA = new WeekDay("TBA", "TBA", 7, 'A', false);
	
	//enumeration initialization
	static {
		SUNDAY.register();
		MONDAY.register();
		TUESDAY.register();
		WEDNESDAY.register();
		THURSDAY.register();
		FRIDAY.register();
		SATURDAY.register();
		TBA.register();
	}

	/**
	 * Return the instance corresponding to the name
	 * 
	 * @param name the enumeration name
	 * @return the enumeration instance
	 */
	public static WeekDay valueOf(String name){
		return values.get(name.toUpperCase());
	}

	/**
	 * Return an array with the enumeration values
	 * 
	 * @return array containing enumeration values
	 */
	public static WeekDay[] values() {
		return values.values().toArray(new WeekDay[values.size()]);
	}
	
	/** 
	 * dayIndex = index of day into week, for graphical display
	 * dayName = english day name
	 * dayChar = typical single character abbreviation
	 * concrete = is a real WeekDay not a placeholder for TBA 
	 */
	private final char dayChar;
	private final boolean concrete;


	/**
	 * Create the WeekDay instance using the specified paramters
	 * 
	 * @param name the name of the week day
	 * @param description the week day description
	 * @param dayIndex the day index (which doubles as ordinal)
	 * @param dayChar the day character representation
	 * @param concrete if the day representation is concrete
	 */
	protected WeekDay(String name, String description, int dayIndex, char dayChar, boolean concrete){
		super(name, description, dayIndex);
		this.dayChar = dayChar;
		this.concrete = concrete;
	}

	/* (non-Javadoc)
	 * @see com.scheduler.util.Enumeration#register()
	 */
	@Override
	protected void register() {
		if(values.get(this.name.toUpperCase()) == null){
			values.put(this.name.toUpperCase(), this);
		}
	}
	
	/**
	 * Return the day index of the week day instance
	 * 
	 * @return index of the day into the week
	 */
	public int dayIndex() {return ordinal;}
	
	/* (non-Javadoc)
	 * @see java.lang.Enum#toString()
	 */
	public String toString() {return this.description;}
	
	/**
	 * Return the character abbreviation of the instance
	 * 
	 * @return typical single character abbreviation
	 */
	public char getDay() {return dayChar;}
	
	/**
	 * Return the weekday instance based on the day character
	 * 
	 * @param day the day character used to define the weekday
	 * @return the weekday instance
	 */
	public static WeekDay getDay(char day) {
		for(WeekDay entry: WeekDay.values()) {
			if (entry.getDay() == day) return entry;
		}
		
		return null;
	}

	/* (non-Javadoc)
	 * @see com.scheduler.model.Concretable#isConcrete()
	 */
	public boolean isConcretelyAnnounced() {
		return this.concrete;
	}

	/* (non-Javadoc)
	 * @see com.scheduler.model.Announcable#isUnAnnounced()
	 */
	public boolean isToBeAnnounced() {
		return !isConcretelyAnnounced();
	}
	
	/**
	 * Return the list of weekdays defined for use in the application
	 * 
	 * @return list of real WeekDay enums
	 */
	public static WeekDay[] getDays(){
		List<WeekDay> values = new ArrayList<WeekDay>(WeekDay.values().length);
		
		//return the list of all valid (real) weekday enums
		for(WeekDay day: WeekDay.values()){
			if(day.isConcretelyAnnounced()){
				values.add(day);
			}
		}
		return values.toArray(new WeekDay[values.size()]);
	}
}
